#include <Arduino.h>
#include <TFT_eSPI.h> // Hardware-specific library
#include <SPI.h>
#include <WiFi.h>
#include <Adafruit_AHTX0.h>
#include <ArduinoJson.h>
#include "BMP.h"

#include <HTTPClient.h>  //http连接
#include <ArduinoJson.h> //引入json

// 字库
#include "font/temp_30.h"
#include "font/font_18_weather.h"
#include "font/font_week_20.h"
#include "font/font_week_30_num.h"
#include "font/font_w_20.h"
#include "font/font_22_now_w.h"

#define NTP1 "ntp1.aliyun.com"
#define NTP2 "ntp2.aliyun.com"
#define NTP3 "ntp3.aliyun.com"
#define WIDTH 160
#define HEIGHT 80
#define I2C_SDA 4 //传感器I2C使用的管脚
#define I2C_SCL 5

//注释的方向是物理上的 ，这里把板子横过来了所以要转换一下
#define KeyL 5    // up 逻辑左
#define KeyR 9    // down  逻辑右
#define KeyD 13   // left 逻辑下
#define KeyU 8    // right 逻辑上
#define KeyO 4    // mid 暂时没有使用
#define REDLED 12 // WIFI开始连接，亮灯，连接成功后，灯灭
HTTPClient http;

// 3日天气数据
String today_status;
int today_max;
int today_min;
String tomorrow_status;
int tomorrow_max;
int tomorrow_min;
String last_status;
int last_max;
int last_min;
String payload = "";
//实时天气数据
String now_status;
int now_temp_feel;
int now_humidity;

String UserKey = "key=059629f9abe341af8861e6f99229d979&unit=m&lang=zh&gzip=n"; // 私钥 https://dev.heweather.com/docs/start/get-api-key
// String Location = "location=101220109&";                                       // 城市代码 https://github.com/heweather/LocationList,表中的 Location_ID
String Location = "location=101190113&";
// 101190113 雨花台
String base = "https://devapi.qweather.com/v7/weather/3d?";           //天气地址
String recive_msg_url = "https://devapi.qweather.com/v7/weather/3d?"; //消息服务器地址
String base_now = "https://devapi.qweather.com/v7/weather/now?";      //消息服务器地址

TFT_eSPI tft = TFT_eSPI(); // Invoke library, pins defined in User_Setup.h
TFT_eSprite spr = TFT_eSprite(&tft);
Adafruit_AHTX0 aht;
WiFiClient client;

// =========================================================================
// Setup
// =========================================================================
// const char *ssid = "Tanggy666"; // WIFI账户
// const char *password = "1qaz!QAZ"; // WIFI密码
//const char *ssid = "TGYiPhone";
//const char *password = "1234567809"; // WIFI密码
const char *ssid = "CMCC-1007";
const char *password = "18851850631";


//const char *host = "192.168.0.0";    //自己PC的ip地址

int16_t gpu_usage;
int16_t cpu_usage;
int16_t ram_usage;
int i = 1;

char stateFlag = 0;  // 主状态机状态
char stateFlag2 = 0; // 附状态机状态
char keyFlag = 0;    // 按键状态

void KeyScan()
{

  if (keyFlag == 1)
  {
    // 检查按键是否释放
    if (digitalRead(KeyU) == 0)
      return;
    else if (digitalRead(KeyD) == 0)
      return;
    else if (digitalRead(KeyL) == 0)
      return;
    else if (digitalRead(KeyR) == 0)
      return;
    else if (digitalRead(KeyO) == 0)
      return;
    else
      keyFlag = 0; //按键已经释放
  }

  else
  {
    if (digitalRead(KeyU) == 0)
    {
      keyFlag = 1;
      stateFlag = stateFlag + 1;
      if (stateFlag > 2)
        stateFlag = 0;
      return;
    }
    else if (digitalRead(KeyD) == 0)
    {
      keyFlag = 1;
      if (stateFlag > 0)
        stateFlag = stateFlag - 1;
      else
        stateFlag = 2;
      return;
    }
    //左键
    else if (digitalRead(KeyL) == 0)
    {
      keyFlag = 1;
      if (stateFlag2 > 0)
        stateFlag2 = stateFlag2 - 1;
      else
        stateFlag2 = 2;
      return;
    }
    //右键
    else if (digitalRead(KeyR) == 0)
    {
      keyFlag = 1;
      stateFlag2 = stateFlag2 + 1;
      if (stateFlag2 > 2)
        stateFlag2 = 0;
      return;
    }
    else if (digitalRead(KeyO) == 0)
    {
      keyFlag = 1;
      stateFlag = 0;
      stateFlag2 = 0;
      return;
    }
  }
}

//获取近3日数据
bool getW()
{
  String url = base + Location + UserKey;
  //添加请求头
  http.begin(url);           // 准备启用连接
  int httpCode = http.GET(); // 发起GET请求
  tft.print(httpCode);
  if (httpCode > 0) // 如果状态码大于0说明请求过程无异常
  {
    if (httpCode == HTTP_CODE_OK) // 请求被服务器正常响应，等同于httpCode == 200
    {
      payload = http.getString(); // 读取服务器返回的响应正文数据
      Serial.println(payload);
    }
    else
    {
      // payload = "{\"code\":\"200\",\"daily\":[{\"tempMax\":\"32\",\"tempMin\":\"25\",\"textDay\":\"晴\"},{\"tempMax\":\"31\",\"tempMin\":\"24\",\"textDay\":\"晴\"},{\"tempMax\":\"30\",\"tempMin\":\"26\",\"textDay\":\"晴\"}]}";
    }
  }
  else
  {
    Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
    // payload = "{\"code\":\"200\",\"daily\":[{\"tempMax\":\"32\",\"tempMin\":\"25\",\"textDay\":\"晴\"},{\"tempMax\":\"31\",\"tempMin\":\"24\",\"textDay\":\"晴\"},{\"tempMax\":\"30\",\"tempMin\":\"26\",\"textDay\":\"晴\"}]}";
  }

  http.end(); // 结束当前连接

  const size_t capacity = 2 * JSON_ARRAY_SIZE(1) + JSON_ARRAY_SIZE(3) + JSON_OBJECT_SIZE(2) +
                          JSON_OBJECT_SIZE(5) + 3 * JSON_OBJECT_SIZE(26) + 1320;
  DynamicJsonDocument doc(capacity);

  DeserializationError error = deserializeJson(doc, payload); //反序列化JSON数据
  tft.print(error.c_str());
  // delay(500);
  if (!error) //检查反序列化是否成功
  {
    // 得到三天的天气json
    DynamicJsonDocument todayW = doc["daily"][0];
    JsonVariant tomorrowW = doc["daily"][1];
    JsonVariant the_day_after_tomorrowW = doc["daily"][2];
    String today_status_str = todayW["textDay"];
    String tomorrow_status_str = tomorrowW["textDay"];
    String last_status_str = the_day_after_tomorrowW["textDay"];

    today_status = today_status_str;
    today_max = todayW["tempMax"];
    today_min = todayW["tempMin"];

    tomorrow_status = tomorrow_status_str;
    tomorrow_max = tomorrowW["tempMax"];
    tomorrow_min = tomorrowW["tempMin"];

    last_status = last_status_str;
    last_max = the_day_after_tomorrowW["tempMax"];
    last_min = the_day_after_tomorrowW["tempMin"];
    tft.println("Json yes");
    return true;
  }
}

//获取实时天气数据
bool get_now_W()
{
  String url = base_now + Location + UserKey;
  //添加请求头
  http.begin(url);           // 准备启用连接
  int httpCode = http.GET(); // 发起GET请求
  tft.print(httpCode);
  if (httpCode > 0) // 如果状态码大于0说明请求过程无异常
  {
    if (httpCode == HTTP_CODE_OK) // 请求被服务器正常响应，等同于httpCode == 200
    {
      payload = http.getString(); // 读取服务器返回的响应正文数据
      Serial.println(payload);
    }
    else
    {
      // payload = "{\"code\":\"200\",\"updateTime\":\"2022-09-15T14:17+08:00\",\"fxLink\":\"http://hfx.link/1tu71\",\"now\":{\"obsTime\":\"2022-09-15T14:14+08:00\",\"temp\":\"21\",\"feelsLike\":\"20\",\"icon\":\"305\",\"text\":\"小雨\",\"wind360\":\"270\",\"windDir\":\"西风\",\"windScale\":\"4\",\"windSpeed\":\"21\",\"humidity\":\"95\",\"precip\":\"0.0\",\"pressure\":\"1000\",\"vis\":\"7\",\"cloud\":\"100\",\"dew\":\"21\"},\"refer\":{\"sources\":[\"QWeather\",\"NMC\",\"ECMWF\"],\"license\":[\"no commercial use\"]}}";
    }
  }
  else
  {
    Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
    // payload = "{\"code\":\"200\",\"updateTime\":\"2022-09-15T14:17+08:00\",\"fxLink\":\"http://hfx.link/1tu71\",\"now\":{\"obsTime\":\"2022-09-15T14:14+08:00\",\"temp\":\"21\",\"feelsLike\":\"20\",\"icon\":\"305\",\"text\":\"小雨\",\"wind360\":\"270\",\"windDir\":\"西风\",\"windScale\":\"4\",\"windSpeed\":\"21\",\"humidity\":\"95\",\"precip\":\"0.0\",\"pressure\":\"1000\",\"vis\":\"7\",\"cloud\":\"100\",\"dew\":\"21\"},\"refer\":{\"sources\":[\"QWeather\",\"NMC\",\"ECMWF\"],\"license\":[\"no commercial use\"]}}";
  }

  http.end(); // 结束当前连接

  const size_t capacity = 2 * JSON_ARRAY_SIZE(1) + JSON_ARRAY_SIZE(3) + JSON_OBJECT_SIZE(2) +
                          JSON_OBJECT_SIZE(5) + 3 * JSON_OBJECT_SIZE(26) + 1320;
  DynamicJsonDocument doc(capacity);

  DeserializationError error = deserializeJson(doc, payload); //反序列化JSON数据
  tft.print(error.c_str());
  // delay(500);
  if (!error) //检查反序列化是否成功
  {
    // 得到当前的天气json
    JsonVariant now_w = doc["now"];
    String now_status_tmp = now_w["text"];
    now_status = now_status_tmp;
    now_temp_feel = now_w["feelsLike"];
    now_humidity = now_w["humidity"];
    tft.println("NowJson yes");
    return true;
  }
}

void temp_hum()
{
  sensors_event_t humidity, temp;
  aht.getEvent(&humidity, &temp); // populate temp and humidity objects with fresh data

  Serial.print("Temperature: ");
  Serial.print(temp.temperature);
  Serial.println(" degrees C");
  Serial.print("Humidity: ");
  Serial.print(humidity.relative_humidity);
  Serial.println("% rH");

  // Draw a black rectangle in sprite so when we move it 1 pixel it does not leave a trail
  // on the black screen background
  spr.drawRect(0, 0, WIDTH, HEIGHT, TFT_BLACK);
  spr.setCursor(0, 0);

  spr.fillSprite(TFT_BLACK);
  spr.setTextColor(TFT_YELLOW, TFT_BLACK);
  spr.setTextFont(2);
  spr.setTextSize(2);
  spr.setCursor(0, 8);
  spr.print("T: ");
  spr.print(temp.temperature, 1); //默认是保留两位小数，这里我们保留一位小数
  spr.loadFont(temp_30);
  spr.setCursor(90, 12);
  spr.printf("℃");
  spr.unloadFont();
  spr.setCursor(0, 40);
  spr.print("H: ");
  spr.print(humidity.relative_humidity, 1);
  spr.println("%");
  spr.pushSprite(0, 0);
}

void temp()
{
  sensors_event_t humidity, temp;
  aht.getEvent(&humidity, &temp); // populate temp and humidity objects with fresh data

  spr.drawRect(0, 0, WIDTH, HEIGHT, TFT_WHITE);
  spr.setCursor(0, 0);

  spr.fillSprite(TFT_WHITE);
  spr.setTextColor(TFT_BLACK, TFT_WHITE);
  spr.setTextFont(2);
  spr.setTextSize(2);
  spr.pushImage(8, 20, 40, 40, bmp3_temp);
  spr.setCursor(60, 24);
  spr.print(temp.temperature, 1);
  spr.loadFont(temp_30);
  spr.setCursor(115, 30);
  spr.printf("℃");
  spr.unloadFont();
  spr.pushSprite(0, 0);
}

void sayWord1()
{
  spr.drawRect(0, 0, WIDTH, HEIGHT, TFT_WHITE);
  spr.setCursor(0, 0);

  spr.fillSprite(TFT_BLACK);
  spr.setTextColor(TFT_WHITE, TFT_BLACK);
  spr.setTextFont(1);
  spr.setTextSize(2);
  spr.println("Life Is A Bith");
  spr.println("Fuck It !");
  spr.pushSprite(0, 0);
}

void sayWord2()
{
  spr.drawRect(0, 0, WIDTH, HEIGHT, TFT_WHITE);
  spr.setCursor(0, 0);

  spr.fillSprite(TFT_WHITE);
  spr.setTextColor(TFT_BLUE, TFT_WHITE);
  spr.setTextFont(2);
  spr.setTextSize(2);
  spr.println("T G Y");
  spr.println("Z Z W");
  spr.pushSprite(0, 0);
}

void Humidity()
{
  sensors_event_t humidity, temp;
  aht.getEvent(&humidity, &temp); // populate temp and humidity objects with fresh data

  spr.drawRect(0, 0, WIDTH, HEIGHT, TFT_WHITE);
  spr.setCursor(0, 0);

  spr.fillSprite(TFT_WHITE);
  spr.setTextColor(TFT_BLACK, TFT_WHITE);
  spr.setTextFont(2);
  spr.setTextSize(2);
  spr.pushImage(8, 20, 40, 40, bmp6_humnew);
  spr.setCursor(60, 24);
  spr.print(humidity.relative_humidity, 1);
  spr.println("%");
  spr.pushSprite(0, 0);
}

void setClock0() //详见http://t.csdn.cn/lNVIv
{

  struct tm timeinfo;
  /*struct tm {
  int tm_sec; // 秒，取值0~59；
  int tm_min; // 分，取值0~59；
  int tm_hour; // 时，取值0~23；
  int tm_mday; // 月中的日期，取值1~31；
  int tm_mon; // 月，取值0~11；
  int tm_year; // 年，其值等于实际年份减去1900；
  int tm_wday; // 星期，取值0~6，0为周日，1为周一，依此类推；
  int tm_yday; // 年中的日期，取值0~365，0代表1月1日，1代表1月2日，依此类推；
  int tm_isdst; // 夏令时标识符，实行夏令时的时候，tm_isdst为正；不实行夏令时的进候，tm_isdst为0；不了解情况时，tm_isdst()为负
  };*/
  if (!getLocalTime(&timeinfo))
  {
    //如果获取失败，就开启网络对时
    Serial.println("Failed to obtain time");

    configTime(8 * 3600, 0, NTP1, NTP2, NTP3);
    return;
  }

  Serial.println(&timeinfo, "%F %T %A"); // 格式化输出:2021-10-24 23:00:44 Sunday
  Serial.println(&timeinfo, "%F");
  Serial.println(&timeinfo, "%T");
  Serial.println(&timeinfo, "%A");
  Serial.print(asctime(&timeinfo)); //默认打印格式：Mon Oct 25 11:13:29 2021
  // Draw a black rectangle in sprite so when we move it 1 pixel it does not leave a trail
  // on the black screen background
  spr.drawRect(0, 0, WIDTH, HEIGHT, TFT_BLACK);
  spr.fillSprite(TFT_BLACK);
  spr.setTextColor(TFT_GREENYELLOW, TFT_BLACK);
  spr.setTextFont(2);
  spr.setTextSize(1);

  spr.setCursor(20, 0);
  spr.print(&timeinfo, "%F"); //显示年份

  //显示星期
  spr.setTextColor(TFT_SKYBLUE);
  spr.loadFont(font_week_20);
  //给星期设置位置
  spr.setCursor(113, 5);
  spr.println("星期");
  spr.unloadFont();

  //时分秒
  spr.setTextFont(2);
  spr.setTextSize(2);
  spr.setTextColor(TFT_ORANGE);
  spr.setCursor(5, 20);
  spr.println(&timeinfo, "%T"); //显示时分秒：hh:mm:ss
  spr.setCursor(118, 25);
  spr.loadFont(font_week_30_num);
  spr.setTextColor(TFT_SKYBLUE);
  switch (timeinfo.tm_wday) //在 时间右边在展示星期几
  {
  case 1:
    spr.println("一");
    break;
  case 2:
    spr.println("二");
    break;
  case 3:
    spr.println("三");
    break;
  case 4:
    spr.println("四");
    break;
  case 5:
    spr.println("五");
    break;
  case 6:
    spr.println("六");
    break;
  case 0:
    spr.println("天");
    break;
  default:
    spr.println("五");
  }
  spr.unloadFont();

  //展示天气当前温度湿度,从实时的获取
  sensors_event_t humidity, temp;
  aht.getEvent(&humidity, &temp); // populate temp and humidity objects with fresh data
  spr.setTextColor(TFT_GREENYELLOW);
  spr.loadFont(font_w_20);
  spr.setCursor(5, 55);
  spr.printf("%-8s %.1f℃ %.0f%% \n", now_status, temp.temperature, humidity.relative_humidity);
  spr.unloadFont();
  spr.pushSprite(0, 0); //从左上角原点显示
}

//单独显示天气
void setClock1()
{
  struct tm timeinfo;
  if (!getLocalTime(&timeinfo))
  {
    //如果获取失败，就开启网络对时
    Serial.println("Failed to obtain time");
    configTime(8 * 3600, 0, NTP1, NTP2, NTP3);
    return;
  }

  Serial.println(&timeinfo, "%F %T %A"); // 格式化输出:2021-10-24 23:00:44 Sunday
  Serial.println(&timeinfo, "%F");
  Serial.println(&timeinfo, "%T");
  Serial.println(&timeinfo, "%A");
  Serial.print(asctime(&timeinfo)); //默认打印格式：Mon Oct 25 11:13:29 2021

  // Draw a black rectangle in sprite so when we move it 1 pixel it does not leave a trail
  // on the black screen background
  spr.drawRect(0, 0, WIDTH, HEIGHT, TFT_BLACK);
  spr.fillSprite(TFT_BLACK);
  spr.setTextColor(TFT_YELLOW, TFT_BLACK);
  spr.setTextFont(2);
  // spr.setTextSize(1);
  // spr.setCursor(0, 0);           //从左上角原点显示
  // spr.setCursor(40, 0);spr.println(&timeinfo, "%F");
  spr.setTextSize(2);
  // spr.setTextFont(2);
  // spr.setCursor(14, 16);spr.println(&timeinfo, "%A");
  // spr.setTextSize(2);
  spr.setCursor(24, 24);
  spr.println(&timeinfo, "%T"); //显示时分秒：hh:mm:ss
  // spr.setTextSize(1);
  spr.pushSprite(0, 0); //从左上角原点显示
}

void setClock2()
{
  // Draw a black rectangle in sprite so when we move it 1 pixel it does not leave a trail
  // on the black screen background
  spr.drawRect(0, 0, WIDTH, HEIGHT, TFT_WHITE);
  spr.fillSprite(TFT_WHITE);
  spr.setTextColor(TFT_BLACK, TFT_WHITE);
  spr.setTextFont(2);
  spr.setTextSize(1);
  // spr.setCursor(0, 0);           //从左上角原点显示
  // spr.setCursor(40, 0);spr.println(&timeinfo, "%F");
  spr.pushImage(0, 8, 64, 64, bmp8_gif[i]); //调用图片数据
  i += 1;
  if (i > 4)
  {
    i = 0;
  }
  delay(100);
  // spr.pushImage(0,0,64,64,bmp2_lbili);
  spr.setCursor(80, 22);
  spr.println("Code by");
  spr.setCursor(90, 39);
  spr.println("TGY");
  spr.pushSprite(0, 0); //从左上角原点显示
}

// 接受网络留言板的消息
void recive_msg()
{
  spr.drawRect(0, 0, WIDTH, HEIGHT, TFT_WHITE);
  spr.fillSprite(TFT_BLACK); // LCD清空
  spr.setCursor(0, 0);
  spr.setTextColor(TFT_RED, TFT_BLACK);
  spr.setTextFont(2);
  spr.setTextSize(1);
  spr.println("Message received:");
  spr.setCursor(1, 20);
  spr.setTextFont(1);
  spr.setTextSize(2);
  spr.setTextColor(TFT_LIGHTGREY, TFT_BLACK);
  spr.println("Talk is cheap\nShow me the code.");
  spr.pushSprite(0, 0); //从左上角原点显示
}
// 显示全部天气
void show_Weather()
{
  spr.drawRect(0, 0, WIDTH, HEIGHT, TFT_WHITE);
  spr.fillSprite(TFT_BLACK); // LCD清空
  spr.loadFont(font_18_weather);
  spr.setCursor(0, 5);
  spr.setTextColor(TFT_BLUE, TFT_BLACK);
  spr.println("日期  天气 最高 最低");
  spr.setTextColor(TFT_ORANGE, TFT_BLACK);
  spr.setCursor(0, 28);
  spr.printf("今天:%6s %d℃ %d℃\n", today_status, today_max, today_min);
  spr.printf("明天:%6s %d℃ %d℃\n", tomorrow_status, tomorrow_max, tomorrow_min);
  spr.printf("后天:%6s %d℃ %d℃\n", last_status, last_max, last_min);
  spr.unloadFont();
  spr.pushSprite(0, 0);
}

void show_Weather_now()
{

  struct tm timeinfo;
  if (!getLocalTime(&timeinfo))
  {
    //如果获取失败，就开启网络对时
    Serial.println("Failed to obtain time");
    configTime(8 * 3600, 0, NTP1, NTP2, NTP3);
    return;
  }

  //时间
  spr.drawRect(0, 0, WIDTH, HEIGHT, TFT_BLACK);
  spr.fillSprite(TFT_BLACK);
  spr.setTextColor(TFT_YELLOW, TFT_BLACK);
  spr.setTextFont(2);
  spr.setTextSize(1);
  spr.setCursor(48, 2);
  spr.println(&timeinfo, "%T"); //显示时分秒：hh:mm:ss
  //天气
  spr.setTextColor(TFT_ORANGE, TFT_BLACK);
  spr.setCursor(0, 20);
  spr.loadFont(font_22_now_w);
  spr.printf("现在天气:%s", now_status);
  spr.println();
  spr.printf("体感温度:\t%d℃", now_temp_feel);
  spr.println();
  spr.printf("体感湿度:\t%d%%", now_humidity);
  spr.unloadFont();
  spr.println();
  spr.pushSprite(0, 0); //从左上角原点显示
}

void refresh()
{
  struct tm timeinfo;
  if (!getLocalTime(&timeinfo))
  {
    //如果获取失败，就开启网络对时
    Serial.println("Failed to obtain time");
    configTime(8 * 3600, 0, NTP1, NTP2, NTP3);
    return;
  }
  //半个小时刷新一次实时天气
  if ((timeinfo.tm_min % 30 == 0) && (timeinfo.tm_sec % 59 == 0))
  {
    get_now_W();
  }
  // 2个小时刷新一次预报天气
  if ((timeinfo.tm_hour % 2 == 0) && (timeinfo.tm_min % 59 == 0) && (timeinfo.tm_sec % 59 == 0))
  {
    getW();
  }
}

void setup()
{
  Serial.begin(115200);

  pinMode(KeyU, INPUT_PULLUP);
  pinMode(KeyD, INPUT_PULLUP);
  pinMode(KeyL, INPUT_PULLUP);
  pinMode(KeyR, INPUT_PULLUP);
  pinMode(KeyO, INPUT_PULLUP);
  pinMode(REDLED, OUTPUT);

  Wire.begin(I2C_SDA, I2C_SCL);
  Serial.println("Adafruit AHT10 demo!");

  if (!aht.begin())
  {
    Serial.println("Could not find AHT? Check wiring");
    while (1)
      delay(10);
  }
  Serial.println("AHT10 found");

  tft.init();
  tft.setRotation(3);
  tft.setTextFont(2);

  // Create a sprite of defined size
  spr.createSprite(WIDTH, HEIGHT);

  // Clear the TFT screen to black
  tft.fillScreen(TFT_BLACK);
  tft.setTextColor(TFT_YELLOW, TFT_BLACK);
  // tft.setTextSize(1);
  tft.setCursor(25, 12);
  tft.println("Power by");
  tft.setCursor(25, 28);
  tft.setTextSize(2);
  tft.println("Arduino");
  delay(2000);

  WiFi.begin(ssid, password);
  Serial.println();
  Serial.print("WIFI Connecting");
  tft.fillScreen(TFT_BLACK); // LCD清空
  tft.setCursor(0, 0);
  tft.setTextSize(1);
  tft.print("WIFI Connecting");

  while (WiFi.status() != WL_CONNECTED)
  {
    digitalWrite(REDLED, 1);
    delay(500);
    Serial.print(".");
    tft.print(".");
    digitalWrite(REDLED, 0);
  }
  // 从网络时间服务器上获取并设置时间
  configTime(8 * 3600, 0, NTP1, NTP2, NTP3);
  tft.println();
  tft.println("WiFi connected!");
  tft.fillScreen(TFT_BLACK); // LCD清空
  tft.setCursor(0, 0);
  tft.setTextFont(1);
  tft.print("getting weather ...");
  if (getW())
  {
    tft.println("weather 3d update!");
  };
  if (get_now_W())
  {
    tft.println("weather now update!");
  };

  delay(500);
  tft.fillScreen(TFT_BLACK); // LCD清空
  tft.setCursor(4, 20);
  tft.setTextSize(2);
  tft.println("Ready!!! GO");
  tft.fillScreen(TFT_BLACK);
}

void loop()
{
  KeyScan();         // 按键扫描
  switch (stateFlag) // 主状态机
  {
  case 0: // 显示时间

    switch (stateFlag2) // 副状态机
    {
    case 0: // 显示详细时间

      setClock0();

      break;

    case 1: // 显示时分秒

      setClock1();

      break;

    case 2: // 显示小张吃土了

      setClock2();

      break;
    default:
      stateFlag = 0;
      break;
    }

    break;

  case 1: // 显示温湿度

    switch (stateFlag2) // 副状态机
    {
    case 0: // 显示详细时间

      temp_hum();

      break;

    case 1: // 显示时分秒

      temp();

      break;

    case 2: // 显示小张吃土了

      Humidity();

      break;

    case 3: // 回到首页

      setClock0();

      break;
    default:
      stateFlag = 0;
      break;
    }

    break;

  case 2: // 显示天气

    switch (stateFlag2) // 副状态机
    {
    case 0: // 显示详细

      // PC_infor();
      show_Weather();

      break;

    case 1: // 显示GPU

      // PC_infor1();
      show_Weather_now();

      break;

    case 2: // 显示CPU

      // PC_infor2();
      recive_msg();

      break;
    default:
      stateFlag = 0;
      break;
    }

    break;
  default:
    stateFlag = 0;
    break;
  }
  //定时刷新天气数据
  refresh();
}
